<?php

namespace app\api\controller;

use app\admin\model\admin\Admin;
use app\admin\model\channel\Channel;
use app\api\model\merchant\MerchantModel;
use app\api\model\merchant\MerchantOrderBill;
use app\api\model\order\Order;
use app\BaseController;
use app\logic\job\CanLangJob;
use app\Request;
use think\exception\ValidateException;
use think\facade\Log;
use think\facade\Queue;
use ulit\CryptAES;
use ulit\thirdPayment\SafePay;
use ulit\thirdPayment\CanLangPay;
use yzh52521\EasyHttp\Http;

class Payment extends BaseController
{


    public function pay(Request $request){


        if($request->isPost()){

            $params = $request->only([
                'appid', 'secret', 'channel_code','card_no',
                'name', 'withdraw_type', 'remark', 'amount',
                'account_type', 'bank_name', 'brach_bank_code', 'body', 'sign','out_trade_id','notify_url','callback_url','out_trade_id'
            ]);


            $MemberKeyInfo= MerchantModel::getMerchantInfo($params['appid'],$params['secret']);; //获取商户密钥

           $admin_info= Admin::where(['id'=>$MemberKeyInfo->admin_id])->field(['rate','each_time_add_money','channel_ids'])->find();

            if(empty($MemberKeyInfo)){

                return $this->error('商户信息错误！');
            }
            //校验规则
            $rules = [
                'appid' => ['require','number','length'=>'1,10'],
                'secret' => ['require'],
                'out_trade_id' =>['require','max'=>32,'unique'=>'order'],
                'notify_url' => ['require',],
               // 'callback_url' => ['require',],
//            'ip' => ['require','ip'],
                'amount' => ['require','float','between'=>"1,1000000"],
                'withdraw_type' => ['require',],
                'channel_code' => ['alphaDash','length'=>'2,64'],
                'sign' => ['require','length'=>'10,255'],
            ];

            $message=[
                'appid.require'  => ['code' => 53003, 'msg' => 'appid必填'],
                'secret.require'  => ['code' => 53003, 'msg' => 'secret必填'],
                'amount.require'  => ['code' => 53003, 'msg' => '金额必须'],
                'out_trade_id.max'  => ['code' => 53004, 'msg' => '订单号最大长度为32位'],
                'money.between'  => ['code' => 53005, 'msg' => '金额必须在1-1000000之间'],
                'out_trade_id.unique'  => ['code' => 53004, 'msg' => '订单号已经存在'],
                'notify_url.require'  => ['code' => 53007, 'msg' => '回调通知地址必填'],
              //  'callback_url.require'  => ['code' => 53007, 'msg' => '返回地址必填'],
                'withdraw_type.require'  => ['code' => 53009, 'msg' => '支付类型必填'],
                'sign.require'  => ['code' => 53010, 'msg' => '签名必填'],
                'sign.length'  => ['code' => 53010, 'msg' => '签名最大长度255'],
            ];
            $out_trade_id= input('post.out_trade_id');

         // $signs=makeApiSign($params,$MemberKeyInfo->key);

            if ($MemberKeyInfo->money<0 || (($MemberKeyInfo->money-input('amount'))<0)){
               return $this->error('余额不足');
           }
            if($MemberKeyInfo->ip_switch==1){
                $ips=$MemberKeyInfo->ip;
                $ip=$request->ip();
                if(!in_array($ip,$ips)){
                    $msg=[
                        'code'=>530011,
                        'msg'=>'请把ip添加到白名单'
                    ];
                    return $this->result($msg);
                }
            }
            if(!verifyApiSign($params,$MemberKeyInfo->key)){
                $msg=[
                    'code'=>530007,
                    'msg'=>'签名错误！'
                ];
                return $this->result($msg);
           };
            try {
                $this->validate($params, $rules, $message);
                $order_sn=getRandOrderSn();
                $cardNo=input('card_no');
                $name =input('name');
                $withdrawType=input('withdraw_type');
                $remark=input('remark');
                $amount= input('amount');
                $accountType =input('account_type');
                $channel_info=Channel::where(['code'=>$request->param('channel_code')])->find();
                 if(!$channel_info){
                     return  $this->error('通道编码错误');
                 }

                 if(!in_array($channel_info->id,$admin_info->channel_ids)){
                     return  $this->error('请联系管理员开通通道');
                 }

                $admin_info->rate ? $commission = floatval($amount)*($admin_info->rate/100):$commission=0;
                $commission>0 ? $actual_amount=$amount-$commission:$actual_amount=$amount; //实际到账金额

                $actual_amount=($actual_amount-$admin_info->each_time_add_money);
                $actual_amount=amountFormat($actual_amount);//填充最后2位数
                if($actual_amount<0.1){
                    return  $this->error('金额不能小于手续费');
                }
                $add=[
                    'appid'=>$request->param('appid'),
                    'secret'=>$request->param('secret'),
                    'order_sn'=>$order_sn,
                    'merchant_id'=>$MemberKeyInfo->id,
                    'channel_id'=>$channel_info->id,
                    'out_trade_id'=>$out_trade_id,
                    'amount'=>$amount,
                    'status'=>0,
                    'commission'=>($commission+$admin_info->each_time_add_money),
                    'actual_amount'=>$actual_amount,
                    'third_ext_json'=>$request->param(''),
                ];
                $notifyUrl=$request->domain()."/api.php/Payment/notify";
                $res=Order::submitOrder($add);
                if($res){
                    $orderTitle='沧澜科技有限公司';
                    $showName=input('show_name');
                   $callbackInfo=CanLangPay::getInstance()->withdraw($order_sn,$actual_amount,$withdrawType,$cardNo,$name,$remark,$showName,$notifyUrl,$orderTitle,$accountType);
                    if($callbackInfo['code']==10000){
                        $status = match ($callbackInfo['status']) {
                            'SUCCESS' => 1,
                            'REFUND' => 6,
                            'DEALING' => 2,
                            default => 4,
                        };

                        Order::where(['order_sn'=>$order_sn])->update(['status'=>$status]);

                        $callbackInfo['order_sn']=$order_sn;
                        $params=[
                            'order_sn'=>$order_sn,
                        ];
                        insCheckRedis($order_sn); //加入队列
                        Queue::later(2, 'app\logic\job\CanLangJob',$params); //延迟2s
                        $arr=[
                            'order_sn'=>$order_sn,
                            'order_id'=>$callbackInfo['order_id'],
                            'status'=>$status,
                            'trans_amount'=>$actual_amount,
                        ];
                        return    $this->success($arr);
                    }else{
                        Order::where(['order_sn'=>$order_sn])->update(['pay_error_json'=>$callbackInfo]);

                        return    $this->error($callbackInfo['msg']);
                    }
                }else{
                  
                    return    $this->error('添加订单失败');
                }

            }catch (ValidateException $e){
                // 验证失败 输出错误信息

                Log::write($e->getMessage());

                return $this->result($e->getError());
            }


        }

        return $this->error('未知错误');

    }

    public function findOrder(Request $request){

        $params=$request->param();

        $MemberKeyInfo= MerchantModel::getMerchantInfo($params['appid'],$params['secret']);; //获取商户密钥
        if(empty($MemberKeyInfo)){

            return $this->error('商户信息错误！');
        }
            if(!verifyApiSign($params,$MemberKeyInfo->key)){
                $msg=[
                    'code'=>530007,
                    'msg'=>'签名错误！'
                ];
                return $this->result($msg);
            };

        $out_trade_id=$request->param('out_trade_id');

        $order_info=Order::where(['out_trade_id'=>$out_trade_id])->field(['order_sn','channel_id'])->find();

        if(!$order_info){
            return $this->error('订单信息不存在');
        }

        $Channel=Channel::where(['id'=>$order_info->channel_id])->value('code');
        if($Channel=='Safe'){
            $result=$this->SafeOrderInfo($order_info->order_sn);

            return $this->success($result);
        }elseif($Channel=='Canlang'){
            $result=$this->CanLangOrder($order_info->order_sn);
            if($result['code']==200){
                $status = match ($result['status']) {
                    'SUCCESS' => 1,
                    'REFUND' => 6,
                    'DEALING' => 2,
                    default => 4,
                };
                $arr=[
                    'order_sn'=>$result['out_biz_no'],
                    'order_id'=>$result['order_id'],
                    'status'=>$status,
                    'trans_amount'=>$result['trans_amount'],
                    'pay_date'=>$result['pay_date']
                ];

                return $this->result($arr);
            }else{
                return $this->error($result['msg']);
            }



        }
    }

    public function queryBalance(Request $request){
        $params=$request->param();

        $MemberKeyInfo= MerchantModel::getMerchantInfo($params['appid'],$params['secret']);; //获取商户密钥
        if(empty($MemberKeyInfo)){

            return $this->error('商户信息错误！');
        }

        if(!verifyApiSign($params,$MemberKeyInfo->key)){
            $msg=[
                'code'=>530007,
                'msg'=>'签名错误！'
            ];
            return $this->result($msg);
        };

        $balance=$MemberKeyInfo->money;
      return  $this->success(['balance'=>$balance]);


    }


    public function SafeOrderInfo($order_sn){

        $result=SafePay::getInstance()->query($order_sn);
        $res=json_decode($result,true);
        $res['code'] ==20000 ?$code=200:$code=$res['code'];
        $data['orderCode']=$res['result']['orderCode'];
        $data['payMoney']=$res['result']['payMoney'];
        $data['payTime']=$res['result']['payTime'];
        $data['orderStatus']=$res['result']['orderStatus'];
        $data['remark']=$res['result']['remark'];
        return $this->result(['code'=>$code,'msg'=>$res['message'],'data'=>$data]);
    }

    public function CanLangOrder($order_sn)
    {
        return CanLangPay::getInstance()->query($order_sn);

    }


    public function notify()
    {
        $data=input('');
        $status = match ($data['status']) {
            'SUCCESS' => 1,
            'REFUND' => 6,
            'DEALING' => 2,
            default => 4,
        };

        Order::where(['order_sn'=>$data['out_biz_no']])->update(['status'=>$status,'pay_ext_json'=>$data,'notify_state'=>1]);
        $info=Order::where(['order_sn'=>$data['out_biz_no']])->field(['third_ext_json','merchant_id','commission','notify_state'])->find();

        $log['order_sn']=$info['order_sn'];
        $log['merchant_id']=$info['merchant_id'];
        $log['money']=$info['commission'];
        $true=MerchantOrderBill::createLog($log);
        if ($status == 1 && $true) {
            MerchantModel::where(['id' => $info['merchant_id']])
                ->dec('money', $info['commission'])->update();
        }

        $ext=$info->third_ext_json;
        $arr=[
            'order_sn'=>$data['out_biz_no'],
            'order_id'=>$data['order_id'],
            'status'=>$status,
             'pay_date'=>$data['pay_date']
        ];
        $aec = new CryptAES();
        $Merchant=MerchantModel::where(['id' => $info['merchant_id']])->field(['key','appid','secret'])->find();
        $pasta=$aec->aesEncode(json_encode($arr,JSON_UNESCAPED_UNICODE),$Merchant['key']);
        $send['code']=200;
        $send['msg']='success';
        $send['data']=$pasta;
        $dd=Http::asJson()->post($ext['notify_url'], $send);
        Log::write("已经回调地址".$ext['notify_url'].'data->'.json_encode($arr,JSON_UNESCAPED_UNICODE));
        Log::write("回调结果".$ext['notify_url'].'data->'.json_encode($dd->array(),JSON_UNESCAPED_UNICODE));

        exit("success");
    }

}